home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / comm / bbs / cit_src_AD08.lha / sysdep4.c < prev    next >
C/C++ Source or Header  |  1998-07-25  |  15KB  |  462 lines

  1. /**
  2.   Citadel Message procesing routines
  3. **/
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #include "ctdl.h"
  8.  
  9. extern CONFIG      cfg;   /* Lots an lots of variables    */
  10. extern logBuffer   logBuf;    /* Person buffer    */
  11.  
  12. char *NormalformDate(void);
  13.  
  14.  
  15. struct variables
  16.   {
  17.   char *ourname;     /* name of the variable */
  18.   char type;         /* type of variable */
  19.   union
  20.     {
  21.     UNS_16 *where; /* offset into codeBuf */
  22.     char   *addr;  /* char data pointer */
  23.     void   (*func1)(char *);
  24.     char  *(*func2)(void);
  25.     long   (*func3)(void);
  26.     long   id;
  27.     } object;
  28.   };
  29.  
  30.  
  31. #define CHAR_PTR    0   /* item is a character string pointer */
  32. #define CFGB_PTR    1   /* item is offset into codeBuf        */
  33. #define FUNC1_PT    2   /* Function: void  (func1 *)(char *target) */
  34. #define FUNC2_PT    3   /* Function: char *(func2 *)(void) */
  35. #define FUNC3_PT    4   /* Function: long  (func3 *)(void) */
  36. #define IARG1_PT    5   /* Argument # 1 Integer    */
  37. #define SARG1_PT    6   /* Argument # 1 String ptr */
  38. #define IARG2_PT    7   /* Argument # 2 Integer    */
  39. #define SARG2_PT    8   /* Argument # 2 String ptr */
  40. #define IARG3_PT    9   /* Argument # 3 Integer    */
  41. #define SARG3_PT   10   /* Argument # 3 String ptr */
  42. #define NEW_LINE   11   /* special: add a new line and space*/
  43. #define INT_PTR    12   /* integer data item */
  44. #define SPACE_CH   13   /* special: add a space */
  45. #define BACK_SPC   14   /* special: add a ^H character to the messge */
  46. extern char *SysVers;
  47. extern char  *VERSION;
  48. extern char lastuser[];
  49.  
  50. #define MAXVARS (29)
  51.  
  52. static long message_sector_value(void);
  53.  
  54. struct variables variable[MAXVARS] =
  55.   {
  56.     { "variant",     CHAR_PTR, (unsigned short *)&VARIANT_NAME    },
  57.     { "version",     CHAR_PTR, (unsigned short *)&VERSION_NAME    },
  58.     { "sysvers",     CHAR_PTR, (unsigned short *)&SYSDEP_NAME     },
  59.     { "baseroom",    CFGB_PTR, (unsigned short *)&cfg.bRoom       },
  60.     { "sysop",       CHAR_PTR, (unsigned short *)&cfg.SysopName   }, /* 5 */
  61.     { "nodetitle",   CFGB_PTR,                  &cfg.nodeTitle    },
  62.     { "nodename",    CFGB_PTR,                  &cfg.nodeName     },
  63.     { "nodedomain",  CFGB_PTR,                  &cfg.nodeDomain   },
  64.     { "nodeid",      CFGB_PTR,                  &cfg.nodeId       },
  65.     { "mainfloor",   CFGB_PTR,                  &cfg.MainFloor    }, /*10*/
  66.     { "curruser",    CHAR_PTR, (unsigned short *)&logBuf.lbname   },
  67.     { "ulprotocols", FUNC1_PT, (unsigned short *)UpProtsEnglish   },
  68.     { "dlprotocols", FUNC1_PT, (unsigned short *)DownProtsEnglish },
  69.     { "doorlist",    FUNC1_PT, (unsigned short *)DoorHelpListing  },
  70.     { "lastuser",    CHAR_PTR, (unsigned short *)&lastuser        },/*15*/
  71.     { "privileges",  FUNC2_PT, (unsigned short *)Display_Privledges},
  72.     { "callcount",   FUNC3_PT, (unsigned short *)Get_Call_Count   },
  73.     { "ia1",         IARG1_PT, (unsigned short *) 1               },
  74.     { "sa1",         SARG1_PT, (unsigned short *) 1               },
  75.     { "ia2",         IARG2_PT, (unsigned short *) 2               }, /*20*/
  76.     { "sa2",         SARG2_PT, (unsigned short *) 2               },
  77.     { "ia3",         IARG3_PT, (unsigned short *) 3               },
  78.     { "sa3",         SARG3_PT, (unsigned short *) 3               },
  79.     { "currtime",    FUNC2_PT, (unsigned short *)Current_Time     },
  80.     { "currdate",    FUNC2_PT, (unsigned short *)NormalformDate   }, /*25*/
  81.     { "messages",    FUNC3_PT, (unsigned short *)message_sector_value },
  82.     { "s",           SPACE_CH, NULL                               },
  83.     { "b",           BACK_SPC, NULL                               },
  84.     { "n",           NEW_LINE, NULL                               }
  85.  
  86. /***
  87.     { "lastcall"    CHAR_PTR,(unsigned short *) NULL },
  88.     { "events"      CHAR_PTR(unsigned short *) NULL },
  89.     { "rooms"       CHAR_PTR(unsigned short *) NULL },
  90.     { "roomsused"   CHAR_PTR(unsigned short *) NULL },
  91.     { "lastmessage" CHAR_PTR(unsigned short *) NULL },
  92.     { "logs"        CHAR_PTR(unsigned short *) NULL },
  93.     { "logsused"    CHAR_PTR(unsigned short *) NULL },
  94.     { "lenmessage"  CHAR_PTR(unsigned short *) NULL },
  95. **/
  96.   };
  97.  
  98. struct  Cit_Msg
  99.   {
  100.   struct Cit_Msg *link;/* link to common hashed messages */
  101.   char MsgId[9];       /* Message Identifier */
  102.   char MsgText[72];    /* Message Text */
  103.   };
  104.  
  105. #define MAX_MSGS  ( 523 ) /* good sized prime number */
  106.  
  107. static struct Cit_Msg *Message_Table[MAX_MSGS];   /* dynamic message table */
  108.  
  109. /**
  110.   The message file is made up of a count of the messages
  111.   plus one line per message.  Each message is made up of a
  112.   message ID(8 characters), plus the actual text(71 characters or less).
  113. **/
  114.  
  115. static long message_sector_value()
  116.   {
  117.   return (long)cfg.maxMSector;
  118.   }
  119.  
  120.  
  121. static int Load_Items(FILE *fp);
  122. static int Hashed_Msg(char *text);
  123. void Load_Citadel_Messages(void);
  124. char *NormalformDate()
  125.   {
  126.   return DisplayDate(formDate());
  127.   }
  128.  
  129. static int Hashed_Msg(char *text)
  130.   {
  131.   int result;
  132.   int cnt;
  133.   for( result=0, cnt=0; text[cnt] != '\0'; cnt++)
  134.     result = ( result << 1 ) + toupper(text[cnt]);
  135.   result %= MAX_MSGS;
  136.   return result;
  137.   }
  138.  
  139. static int Load_Items(FILE *fp)
  140.   {
  141.   int cnt;
  142.   char *p;
  143.   char Text[200];        /* Message Text */
  144.   struct Cit_Msg *ptr;  /* hashed Entry Value */
  145.   struct Cit_Msg *tptr; /* hashed Entry Value for duplicate check */
  146.   /**
  147.     Get the ID, hash it, then add it to the table
  148.     File format:
  149.     # comment lines are ignored, and start with "#"
  150.     1      8       10                  79
  151.     IIIIIIII<space>TTTTTTTTTTTTTTTTTTTTTT<newline>
  152.   **/
  153.   while( fgets(Text,sizeof(Text),fp) )
  154.     {
  155.     if( strlen(Text) > 79 )
  156.       {
  157.       printf("WARNING: CIT_MESSAGE.SYS text line too long, Truncated:\n%s\n",Text);
  158.       Text[79] = '\0';
  159.       };
  160.     if( Text[0] == '#' )continue;                /* skip comment characters */
  161.     if( (p=strchr(Text,'\n')) != NULL)*p = '\0'; /* get rid of newline      */
  162.     Text[8] = '\0';
  163.     ptr = calloc(1,sizeof(struct Cit_Msg));     /* get an element          */
  164.     if( ptr == NULL)return 2;                   /* No memory available     */
  165.     strcpy(ptr->MsgId,   &Text[0]);
  166.     strcpy(ptr->MsgText, &Text[9]);             /* build entry             */
  167.     cnt        = Hashed_Msg(&Text[0]);
  168.     tptr       = Message_Table[cnt];
  169. /**
  170.   Look up the message to be sure we don't have a duplicate
  171. **/
  172.     while( tptr != NULL )
  173.       {
  174.       if( stricmp(tptr->MsgId, ptr->MsgId) == 0 )break;
  175.       tptr = tptr->link;
  176.       };
  177.     if( tptr != NULL )
  178.       printf("Error:  Duplicate Message Code(%s) in Cit_Message.Sys\n",Text);
  179.     ptr->link  = Message_Table[cnt];
  180.     Message_Table[cnt] = ptr;
  181.     };
  182.   return 0;
  183.   }
  184.  
  185. #define MAX_LINE (120)
  186.  
  187. extern MessageBuffer     msgBuf;
  188. static void Fix_Line(char *line, char *buffer, long arg1, long arg2, long arg3);
  189.  
  190. static void Fix_Line(char *line, char *buffer, long arg1, long arg2, long arg3)
  191.   {
  192.   struct variables *vptr;
  193.   char *ptr;
  194.   char *tmp;
  195.   long inttmp;
  196.   int index = strlen(buffer);
  197.   while( *line != '\0' )
  198.     {
  199.     if( *line == '^' )
  200.       {
  201.       int i;
  202.       ptr = ++line;
  203.       buffer[index] = '\0';
  204.       for( i=0; i < MAXVARS; i++)
  205.         {
  206.         vptr = &variable[i];
  207.         if( strncmp(vptr->ourname, ptr, strlen(vptr->ourname)) == 0)
  208.           {
  209.           switch (vptr->type)
  210.             {
  211.             case BACK_SPC: /* insert a backspace character in message */
  212.                buffer[index] = '\b';
  213.                break;
  214.             case NEW_LINE: /* put in a newline and space */
  215.               strcat(buffer,"\n ");
  216.               break;
  217.             case SPACE_CH: /* insert a space */
  218.               strcat(buffer," ");
  219.               break;
  220.             case CHAR_PTR: /* char pointer, direct access */
  221.               strcat(buffer,vptr->object.addr);
  222.               break;
  223.             case CFGB_PTR: /* make a char pointer, then direct access */
  224.               strcat(buffer,&cfg.codeBuf[*vptr->object.where]);
  225.               break;
  226.             case FUNC1_PT: /* call the function, direct to buffer */
  227.               (vptr->object.func1)(lbyte(buffer));
  228.               break;
  229.             case FUNC2_PT: /* call the function, direct access */
  230.               tmp = (vptr->object.func2)();
  231.               strcat(buffer, tmp );
  232.               break;
  233.             case FUNC3_PT: /* call the function, convert number into buffer */
  234.               inttmp = (vptr->object.func3)();
  235.               sprintf(lbyte(buffer),"%ld", inttmp );
  236.               break;
  237.             case INT_PTR:  /* integer argument */
  238.               sprintf(lbyte(buffer), "%ld, *vptr->object.addr");
  239.               break;
  240.             case IARG1_PT: /* argument in call */
  241.               sprintf(lbyte(buffer),"%ld",arg1);
  242.               break;
  243.             case SARG1_PT: /* argument is */
  244.               if( arg1 != NULL )sprintf(lbyte(buffer),"%s",arg1);
  245.               break;
  246.             case IARG2_PT: /* argument in call */
  247.               sprintf(lbyte(buffer),"%ld",arg2);
  248.               break;
  249.             case SARG2_PT: /* argument is */
  250.               if( arg2 != NULL )sprintf(lbyte(buffer),"%s",arg2);
  251.               break;
  252.             case IARG3_PT: /* argument in call */
  253.               sprintf(lbyte(buffer),"%ld",arg3);
  254.               break;
  255.             case SARG3_PT: /* argument is  */
  256.               if( arg3 != NULL )sprintf(lbyte(buffer),"%s",arg3);
  257.               break;
  258.  
  259.             };
  260.           line += strlen(vptr->ourname);
  261.           index = strlen(buffer);
  262.           break;
  263.           }
  264.         };
  265.       if( i == MAXVARS )buffer[index++] = *line++;
  266.       }
  267.     else buffer[index++] = *line++;
  268.     };
  269.   buffer[index] = '\0';
  270.   }
  271.  
  272. static struct Cit_Msg *Look_Up(char *code);
  273.  
  274. static struct Cit_Msg *Look_Up(char *code)
  275.   {
  276.   struct Cit_Msg *ptr;
  277.   ptr = Message_Table[Hashed_Msg(code)];
  278.   if( ptr ==  NULL )return NULL;
  279.   while( ptr != NULL )
  280.     {
  281.     if( stricmp(ptr->MsgId, code) == 0)return ptr;
  282.     ptr = ptr->link;
  283.     };
  284.   return NULL;
  285.   }
  286.  
  287. static char *msgbuffer=NULL;   /* Initialized from available memory */
  288.  
  289. void Output_Citadel_Message(char *pcode,long arg1, long arg2, long arg3)
  290.   {
  291.   char code[9];
  292.   FILE *op;
  293.   char line[MAX_LINE];
  294.   struct Cit_Msg *ptr;
  295. /**
  296.   translate the code into a message
  297. **/
  298.   if( msgbuffer == NULL )    msgbuffer = GetDynamic(MAXTEXT);
  299.   strncpy(code,pcode,6);
  300.   code[6] = '\0';
  301.   strcat(code,expert ? "EX" : "NO");
  302.   code[8] = '\0';
  303.   ptr = Look_Up(code);     /* find the code or return NULL */
  304.   if( ptr == NULL && expert )
  305.     {
  306.     code[6] = 'N';
  307.     code[7] = 'O';
  308.     ptr =  Look_Up(code);
  309.     };
  310.   if( ptr == NULL )
  311.     {
  312.     mPrintf("\n ***Error Code %s\n",code);
  313.     }
  314.   else
  315.     {
  316.     if( ptr->MsgText[0] == '@')
  317.       {
  318.       if( (op=fopen(&ptr->MsgText[1],"r")) == NULL )
  319.         {
  320.         mPrintf("\n *** Error Code %s, filename:%s not found\n",code,&ptr->MsgText[1]);
  321.         }
  322.       else
  323.         {
  324.         msgbuffer[0] = '\0';
  325.         while (fgets(line, MAX_LINE, op) )
  326.           {
  327.           char *p;
  328.           if( (p=strchr(line,'\n')) != NULL)*p = '\0'; /* get rid of newline      */
  329.           Fix_Line(line,msgbuffer, arg1,arg2, arg3);
  330.           if( ( strlen(msgbuffer) + strlen(line) + 500 ) > MAXTEXT )
  331.             {
  332.             mPrintf("%s", msgbuffer);
  333.             msgbuffer[0] = '\0';
  334.             };
  335.           };
  336.         fclose(op);
  337.         };
  338.       }
  339.     else
  340.       {
  341.       msgbuffer[0] = '\0';
  342.       Fix_Line(ptr->MsgText,msgbuffer, arg1, arg2, arg3);
  343.       };
  344.     if( strlen(msgbuffer) > 0 ) mPrintf("%s",msgbuffer);
  345.  
  346.     }
  347.   }
  348.  
  349. void Load_Citadel_Messages()
  350.   {
  351.   int code;       /* Error Code */
  352.   char temp[80];  /* input filename  */
  353.   FILE *fp;       /* input file pointer */
  354. /*  SpecialMessage("Message Initialization"); */
  355.   makeSysName(temp,"Cit_Messages.sys", &cfg.msgArea);
  356.   if( (fp=fopen(temp,/* READ_TEXT*/ "r")) != NULL )
  357.     {
  358.     memset(Message_Table,'\0',sizeof(struct Cit_Msg *) * MAX_MSGS );
  359.     code = Load_Items( fp );
  360.     fclose(fp);
  361.     }
  362.   else code = 1;      /* file will not open */
  363.   if( code != 0 )
  364.     {
  365.     printf(" Filename:%s\n",temp);
  366.     printf(" Load Messages Error code %d\n",code);
  367.     };
  368.   }
  369. extern int       outPut;
  370. extern char      outFlag;
  371. extern char      Showing;
  372. extern char      ReverseMessage;
  373. extern char      pullMessage;
  374. extern int       thisRoom;
  375. extern char      journalMessage;
  376. extern char      MsgStreamEnter;
  377. extern char      echo;           /* Output flag  */
  378. extern char      echoChar;
  379. extern char      loggedIn;       /* Logged in flag      */
  380. extern SListBase Moderators;
  381. extern char      pause_whichMess;
  382. char  Pause_Message_Check()
  383.   {
  384.   /**
  385.     If this is a user, and the user has Pause at end of message
  386.     in their configuration, we will pause here asking for a character.
  387.     We will eat all input first(just incase of line noise).
  388.     A "S" will attempt to stop the message stream.
  389.     A "N" will attempt to skip to next message.
  390.     Basically, we duplicate MABORT() here...
  391.   **/
  392.    char c, toReturn, oldEcho;
  393.    toReturn = FALSE;
  394.    if( outFlag == IMPERVIOUS || outFlag == NET_CALL
  395.     || outPut == DISK )return toReturn;
  396.    if( loggedIn )
  397.      {
  398.      if( logBuf.lbflags.MSG_PAUSE
  399.       && ( ( pause_whichMess != NEWoNLY
  400.           && thisRoom == MAILROOM ) || thisRoom != MAILROOM) )
  401.        {
  402.        if( aide ||
  403.            ( strCmpU(logBuf.lbname, AskForNSMap(&Moderators, thisRoom)) == SAMESTRING
  404.              && strLen(logBuf.lbname) != 0 ))
  405.          {
  406.          Output_Citadel_Message("SYSPAU",NULL, NULL, NULL);
  407.          }
  408.        Output_Citadel_Message("MSGPAU",NULL, NULL, NULL);
  409.        oldEcho = echo;
  410.        echo    = NEITHER;
  411.        echoChar= 0;
  412.        while (MIReady())   inp();   /* eat noise */
  413.        c = toUpper(modIn());        /* accept one character */
  414.        switch (c)
  415.          {
  416.          case 'D':  /* delete the message if you have privileges */
  417.            if( Showing == MSGS &&
  418.                ( aide ||
  419.                  ( strCmpU(logBuf.lbname, AskForNSMap(&Moderators, thisRoom)) == SAMESTRING
  420.                  && strLen(logBuf.lbname) != 0)))
  421.               {
  422.               pullMessage = TRUE;
  423.               toReturn = TRUE;
  424.               };
  425.             break;
  426.           case 'S' : /* stop displaying messages */
  427.             outFlag  = OUTSKIP;
  428.             toReturn = TRUE;
  429.             break;
  430.          case 'J':  /* Journal the Message */
  431.            if( Showing == MSGS &&
  432.                ( aide ||
  433.                  ( strCmpU(logBuf.lbname, AskForNSMap(&Moderators, thisRoom)) == SAMESTRING
  434.                  && strLen(logBuf.lbname) != 0 ) ) )
  435.               {
  436.               journalMessage = TRUE;
  437.               toReturn       = TRUE;
  438.               };
  439.             break;
  440.          case 'E':  /* Enter a Reply */
  441.             if( Showing == MSGS && HasWritePrivs())
  442.               {
  443.               MsgStreamEnter = TRUE;
  444.               outFlag        = OUTSKIP;
  445.               toReturn       = TRUE;
  446.               };
  447.             break;
  448.          case 'R':  /* Reverse the flow */
  449.             if( Showing == MSGS )
  450.               {
  451.               ReverseMessage = TRUE;
  452.               toReturn       = TRUE;
  453.               };
  454.             break;
  455.          };
  456.        echo = oldEcho;
  457.        }
  458.      else if( Showing == MSGS && thisRoom == MAILROOM && pause_whichMess == NEWoNLY)toReturn = TRUE;
  459.      };
  460.   return toReturn;
  461.   }
  462.